/**
 * 旋转刻度盘组件,通过canvas控件绘制值刻度盘,然后横向touch,移动
 * 刻度盘度数,同时通过事件向父组件发送当前度数
 */
Component({
    properties: {
        // 设置canvas的样式,尺寸
        style: String,
        // 初始度数
        degree: {
            type: Number,
            value: 0
        },
        // 允许指示的最小度数
        minDegree: {
            type: Number,
            value: -50
        },
        // 允许指示的最大度数
        maxDegree: {
            type: Number,
            value: 50
        },
    },

    /**
     * 组件的初始数据
     */
    data: {
        // 记录滑动时的起始坐标
        startX: 0,
        // 画布包含画布节点canvas,ctx,width,height
        canvasNode: undefined,
        // 当前指示度数
        preDegree: 0,
        // 当前滑动度数
        currDegree: 0,
        // 刻度盘半径
        dialRadius: 0,
        tcColor:'rgb(48,48,48)'

    },

    /**
     * 组件的方法列表
     */
    methods: {

        /** 滑动开始事件*/
        start(e) {
            // 保存手指触摸屏幕时的起始坐标
            this.setData({
                startX: e.touches[0].pageX
            })
        },
        /**滑动事件*/
        move(e) {
            // 通过当前坐标与触摸起始坐标的距离计算移动度数
            let curX = e.touches[0].pageX;
            let currDegree = this.getCurrDegree(curX);
            // 保存当前度数,触发刻度盘重画函数initDial
            this.setData({
                currDegree: currDegree
            });

        },
        /**滑动结束事件 */
        end(e) {
            let curX = e.changedTouches[0].pageX;
            let currDegree = this.getCurrDegree(curX);
            // 结束触摸后保存当前度数
            this.setData({
                preDegree: currDegree
            })
        },
        // 通过滑动距离计算当前度数
        getCurrDegree(currX) {
            let startX = this.data.startX;
            let currDegree = this.data.preDegree;
            let minDegree = this.data.minDegree;
            let maxDegree = this.data.maxDegree;
            if (Math.abs(currX - startX) > 40) {

                // 滑动距离除以10作为度数
                currDegree += Math.round((currX - startX) / 5);
                // 显示度数范围50度
                currDegree = Math.min(Math.max(minDegree, currDegree), maxDegree);
            }
            return currDegree;
        },
        //获取canvas
        getCanvas() {
            return new Promise((resove, reject) => {
                this.createSelectorQuery()
                    .select('#myCanvas') // 在 WXML 中填入的 id
                    .fields({
                        node: true,
                        size: true
                    })
                    .exec((res) => {
                        resove({
                            canvas: res[0].node,
                            ctx: res[0].node.getContext('2d'),
                            width: res[0].width,
                            height: res[0].height
                        })
                    })
            })
        },

        /**初始时绘制刻度盘 */
        init() {
            // 设置画布相关参数
            const canvasNode = this.data.canvasNode;
            const width = canvasNode.width;
            const height = canvasNode.height;
            const ctx = canvasNode.ctx;
            const canvas = canvasNode.canvas;

            // 初始化画布大小
            const dpr = wx.getWindowInfo().pixelRatio
            canvas.width = width * dpr
            canvas.height = height * dpr
            ctx.scale(dpr, dpr);

            this.setData({
                currDegree: this.data.degree
            })

        },

        /**绘制刻度盘
         * @param {*} degree 
         */
        initDial(degree = 0) {
            const ctx = this.data.canvasNode.ctx;
            const width = this.data.canvasNode.width;
            const height = this.data.canvasNode.height;
            const cx = width / 2;
            const cy = -1 * (this.data.dialRadius - height);
            const radius = this.data.dialRadius - 2;
            // 清空画布
            ctx.clearRect(0, 0, width, height);
            ctx.save();
            // 移动画布中心点
            ctx.translate(cx, cy);
            // 绘制指示点
            ctx.fillStyle = this.data.tcColor;
            ctx.beginPath()
            ctx.moveTo(0, 0); //注释四
            ctx.lineTo(0, radius - height / 2);
            ctx.lineWidth = 2;
            ctx.strokeStyle = this.data.tcColor;
            ctx.lineCap = "round"; //注释五
            ctx.stroke(); //注释六

            // 绘制刻度和数字
            let r = 1; // 刻度圆点直径
            for (let i = degree; i < 360 + degree; i++) {
                // 每两度绘制一个刻度点,每10度绘制一个大一点刻度点
                if (i % 2 == 0 || i % 10 == 0) {
                    if (i % 2 == 0 && i % 10 != 0) {
                        r = 1;
                    } else {
                        r = 2;
                        let txt = i * -1;
                        if (i > 180) {
                            txt += 360;
                        }
                        ctx.fillText(txt, ctx.measureText(txt).width / 2 * -1, radius - 6)
                    }
                    ctx.beginPath()
                    ctx.arc(0, radius, r, 0, 2 * Math.PI);
                    ctx.fill()
                }
                // 每次画布旋转1度
                ctx.rotate(Math.PI / 180);
            }
            ctx.restore();
        },
        // 通过页面隐藏的节点获取设置的文本颜色值
        getUiTCMainColor() {
            return new Promise((resolve, reject) => {
                const _this = this;
                this.createSelectorQuery().select('#color-note').fields({
                    computedStyle: ['color'],
                }, function (res) {
                    resolve(res.color);
                }).exec()
            })
        },

    },
    lifetimes: {
        async attached() {
            // 在组件实例进入页面节点树时执行
            const canvasNode = await this.getCanvas();
            const tcColor = await this.getUiTCMainColor();
            const radius = (canvasNode.width * canvasNode.width) / (8 * canvasNode.height) + canvasNode.height / 2;
            // 计算绘制刻度盘半径
            this.setData({
                canvasNode: canvasNode,
                dialRadius: radius,
                tcColor:tcColor
            })
            this.init();


        },
    },
    // 监听当前度数
    observers: {
        'currDegree': function (currDegree) {
            this.initDial(currDegree);
            // 向父组件发送事件
            this.triggerEvent("change", {
                currDegree: currDegree * -1
            });
        }
    }
})